using System.ComponentModel;
using System.Diagnostics;
using Microsoft.Win32;
using Mod管家.Util;
using SevenZip;

namespace Mod管家
{
    public partial class Form1 : Form
    {
        //全局string变量游戏路径
        private static string? _gamePath; //游戏路径
        private static string? _modPath; //mod路径
        private static string? _dataPath; //补丁路径
        private static bool _firstRun = true;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (_firstRun)
            {
                _firstRun = false;
                Directory.CreateDirectory("./mods");
                DatabaseHelper.SetConnectionString("101.132.40.214", "spirithun", "spirithun", "euU9EgTWW8uOMt8m",
                    3306);
                DatabaseHelper.ConnectToDatabase();
                MessageBox.Show("欢迎使用本软件！软件与计算机绑定，移动复制将无法使用本软件！", "Mod管家", MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }

            if (SafeAppTools.IsGetGamePath())
            {
                _gamePath = GetGamePath.Text = SafeAppTools.GamePath;
                _dataPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC";
                _modPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC\\arc\\DX9";
                GetGamePath.Enabled = false;
                return;
            }

            if (SafeAppTools.IsRegistered()) return;
            Text = "Mod管家 - 未激活";
            MessageBox.Show("软件未激活，请先激活软件！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //载入register窗口
            var register = new Register();
            register.ShowDialog();
            //销毁主窗口
            Close();


        }

        //注册名为GetGamePath的按钮点击事件
        private void GetGamePath_Click(object sender, EventArgs e)
        {
            // 注意，这里传入的应该是没有".exe"的进程名
            var processes = Process.GetProcessesByName("bh6");
            var processesCaps = Process.GetProcessesByName("BH6");
            if (processes.Length == 0 && processesCaps.Length == 0)
            {
                MessageBox.Show("未检测到游戏，请先运行生化危机6！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                try
                {
                    string gamePath = processes[0].MainModule?.FileName ??
                                      throw new InvalidOperationException("无法获取游戏路径。");
                    _gamePath = GetGamePath.Text = gamePath;
                    _modPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC";
                    _dataPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC\\arc\\DX9";
                    processes[0].Kill(); // 终止进程
                    MessageBox.Show("游戏路径获取成功！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    GetGamePath.Enabled = false;
                    var key = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\BH6MOD\Mod管家\AppData");
                    key.SetValue("gamePath", gamePath);
                    key.Close();
                }
                catch (InvalidOperationException ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                //这个异常是为了处理没有足够权限读取其他进程模块信息时的情况
                catch (Win32Exception ex)
                {
                    MessageBox.Show("获取游戏路径失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }


        private void UnLockMod_Click(object sender, EventArgs e)
        {
            if (ModList.SelectedIndex == -1)
            {
                MessageBox.Show("请先选择要解锁的mod！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (UnlockKey.Text == "")
            {
                MessageBox.Show("请输入解锁码！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int status = DatabaseHelper.GetModUnKeyStatus(UnlockKey.Text, ModList.Text);
            switch (status)
            {
                case -1:
                    MessageBox.Show("解锁码无效！请检查您的解锁码！或者联系作者！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -2:
                    MessageBox.Show("解锁码已被使用！请重新获取解锁码！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 1:
                    //弹窗提示，解锁成功
                    MessageBox.Show("解锁成功！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
            }
        }

        private void Scan_Click(object sender, EventArgs e)
        {
            ModList.Items.Clear();
            MessageBox.Show("请将mod文件放到 mods文件夹下软件即可扫描！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
            string[] files = Directory.GetFiles("./mods", "*.7z");
            foreach (string file in files)
            {
                string fileName = Path.GetFileNameWithoutExtension(file);
                ModList.Items.Add(fileName);
            }

            MessageBox.Show("扫描完成！共找到" + files.Length + "个mod文件！", "Mod管家", MessageBoxButtons.OK,
                MessageBoxIcon.Information);
        }

        private void InstallMod_Click(object sender, EventArgs e)
        {
            if (ModList.SelectedIndex == -1)
            {
                MessageBox.Show("请先选择要安装的mod！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (!SafeAppTools.ModExist(ModList.Text)) return;
            var modInfo = SafeAppTools.GetModData(SafeAppTools.ModKey);
            if (modInfo.ModName == null) return;
            if (modInfo.ModUnZipPassword != null)
                UnPackMod(modInfo.ModName, modInfo.ModUnZipPassword);
        }

        /// <summary>
        ///     解压并安装模组
        /// </summary>
        /// <param name="modName">模组文件名，包含路径</param>
        /// <param name="modUnZipPassword">模组解压密码</param>
        private static void UnPackMod(string modName, string modUnZipPassword)
        {
            // 获取当前应用程序域的基础目录
            string basePath = AppDomain.CurrentDomain.BaseDirectory;
            // 拼接7z.dll文件的路径
            string libPath = Path.Combine(basePath, "lib", "7z.dll");
            // 设置7-Zip库的路径
            SevenZipBase.SetLibraryPath(libPath);
            try
            {
                // 创建SevenZipExtractor对象，用于解压模组文件
                using var extractor = new SevenZipExtractor(modName, modUnZipPassword);
                // 解压文件并备份
                ExtractAndBackupFiles(extractor);
                // 显示成功安装模组的消息框
                MessageBox.Show("Mod安装成功！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception e)
            {
                // 打印异常信息到控制台，并重新抛出异常
                Console.WriteLine(e);
                throw;
            }
        }

        /// <summary>
        ///     提取并备份文件。
        ///     使用SevenZipExtractor从压缩文件中提取文件，并在提取前为现有文件创建备份。
        /// </summary>
        /// <param name="extractor">SevenZipExtractor对象，用于处理压缩文件的提取。</param>
        private static void ExtractAndBackupFiles(SevenZipExtractor extractor)
        {
            // 遍历压缩文件中的所有文件信息
            foreach (var archiveFileInfo in extractor.ArchiveFileData)
            {
                // 如果_modPath为空，则跳过当前循环
                if (_modPath == null) continue;

                // 构造文件的完整路径
                string fullPath = Path.Combine(_modPath, archiveFileInfo.FileName);

                // 如果文件已存在
                if (File.Exists(fullPath))
                {
                    // 构造备份文件的路径
                    string backupPath = $"{fullPath}.bak";

                    // 如果备份文件已存在，则删除它
                    if (File.Exists(backupPath))
                    {
                        File.Delete(backupPath);
                    }

                    // 将现有文件移动到备份路径
                    File.Move(fullPath, backupPath);
                }

                // 获取文件所在的目录路径
                string? directoryPath = Path.GetDirectoryName(fullPath);

                // 如果目录存在，则继续下一个文件
                if (Directory.Exists(directoryPath)) continue;

                // 如果directoryPath不为null，则创建该目录
                if (directoryPath != null) Directory.CreateDirectory(directoryPath);
            }

            // 在指定的路径下提取压缩文件的所有内容
            extractor.ExtractArchive(_modPath);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (MessageBox.Show("是否退出？", "Mod管家", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                return;

            if (_modPath != null)
            {
                Directory.Delete(_dataPath+"\\SpiritHun6", true);
                try
                {
                    var di = new DirectoryInfo(_modPath);
                    foreach (var file in di.GetFiles())
                    {
                        // 检查对应的.bak文件是否存在
                        string backupPath = $"{file.FullName}.bak";
                        if (!File.Exists(backupPath)) continue;

                        try
                        {
                            // 如果存在对应的.bak文件，尝试删除当前文件
                            file.Delete();
                        }
                        catch (Exception deleteException)
                        {
                            // 这里可以记录日志或者给用户提示具体的错误信息
                            Console.WriteLine($"删除文件 {file.FullName} 时出错: {deleteException.Message}");
                        }

                        try
                        {
                            // 将.bak还原
                            File.Move(backupPath, backupPath[..^4]);
                        }
                        catch (Exception moveException)
                        {
                            // 这里可以记录日志或者给用户提示具体的错误信息
                            Console.WriteLine($"还原备份文件 {backupPath} 时出错: {moveException.Message}");
                        }
                        // 如果没有对应的.bak文件，说明文件是原本就存在的，不做处理
                    }
                }
                catch (Exception generalException)
                {
                    // 处理目录操作的异常
                    Console.WriteLine($"处理目录 {_modPath} 时出现异常: {generalException.Message}");
                }
            }
            Console.WriteLine("程序正在关闭，已尝试清理由解压操作生成的新文件并还原备份文件。");
            Application.Exit();
        }

    }
}